package com.pds.web.opsOrganization.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pds.common.core.domain.entity.SysDept;
import com.pds.common.core.domain.entity.SysRole;
import com.pds.common.core.domain.entity.SysUser;
import com.pds.common.utils.DateUtils;
import com.pds.common.utils.SecurityUtils;
import com.pds.common.utils.StringUtils;
import com.pds.system.domain.FileUpload;
import com.pds.system.domain.SysUserRole;
import com.pds.system.mapper.*;
import com.pds.utils.FileUtil;
import com.pds.web.area.entity.Area;
import com.pds.web.area.mapper.AreaMapper;
import com.pds.web.company.excel.CompanyContactExcel;
import com.pds.web.opsOrganization.domain.OpsOrganizationInfo;
import com.pds.web.opsOrganization.mapper.OpsOrganizationMapper;
import com.pds.web.opsOrganization.service.IOpsOrganizationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class OpsOrganizationServiceImpl implements IOpsOrganizationService {

    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysDeptMapper sysDeptMapper;
    @Autowired
    private SysConfigMapper sysConfigMapper;
    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;
    @Autowired
    private OpsOrganizationMapper opsOrganizationMapper;
    @Autowired
    private FileUploadMapper fileUploadMapper;
    @Autowired
    private SysUserRoleMapper userRoleMapper;
    @Autowired
    AreaMapper areaMapper;

    /**管理员角色名称*/
    private static final String OPS_ADMIN_ROLE_KEY = "opsAdmin";
    /**普通用户角色名称*/
    private static final String OPS_USER_ROLE_KEY = "opsCommon";
    /**
     * 环保局新增运维机构
     * @param info
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addOrganization(OpsOrganizationInfo info) throws Exception {
        String createBy = SecurityUtils.getLoginUser().getUser().getNickName();
        Date date = DateUtils.parseDate(DateUtils.getTime());
        if(StringUtils.isEmpty(info.getCounty())){
            throw new Exception("请选择地址");
        }

        //判断部门表是否存在同名
        SysDept exixtDept = sysDeptMapper.selectDeptByDeptName(info.getOpsName());
        if ( exixtDept != null && exixtDept.getDelFlag().equals("0")) {
            throw new Exception("添加失败，已存在相同名称企业，请核实");
        }
        //判断用户表是否存在同手机号
        if (sysUserMapper.selectUserByUserName(info.getContactPhone()) != null) {
            throw new Exception("添加失败，其他企业中已存在相同手机号账户，请核实");
        }
        //查询一级部门信息:0环保局，1检测机构，2企业，3运维机构
        //防止修改部门名称，导致无法添加企业机构信息
        SysDept lastDept = sysDeptMapper.getLastDeptByType(3);
        Long parentId = lastDept.getDeptId();
        String ancestors = lastDept.getAncestors();
        String[] ids = ancestors.split(",");
        if(ids.length>=3){
            //是二级以上目录
            parentId = Long.valueOf(ids[2]);
            ancestors = ids[0]+","+ids[1]+","+ids[2];
        }else{
            //是一级目录
            ancestors = ancestors+","+lastDept.getDeptId();
        }

        //增加到部门表
        SysDept dept = new SysDept();
        dept.setParentId(parentId);
        dept.setAncestors(ancestors);
        dept.setDeptName(info.getOpsName());
        dept.setType(3);
        dept.setOrderNum(lastDept.getOrderNum()+1);
        dept.setLeader(info.getContactName());
        dept.setPhone(info.getContactPhone());
        dept.setCreateBy(createBy);
        dept.setCreateTime(date);
        sysDeptMapper.insertDept(dept);
        SysDept temp = new SysDept();
        temp.setDeptId(dept.getDeptId());
        temp.setOrganizationId(dept.getDeptId());
        sysDeptMapper.updateDept(temp);

        //设置联系人为运维机构管理员
        SysUser user = addSysUser(info, dept,OPS_ADMIN_ROLE_KEY,null);

        //存储机构其他基本信息
        info.setOpsId(dept.getDeptId());
        info.setContactUserId(user.getUserId());
        opsOrganizationMapper.insertOpsOrganization(info);
    }

    /**
     * 设置联系人为运维机构管理员
     * @param info
     * @param dept
     * @return
     */
    @Override
    public SysUser addSysUser(OpsOrganizationInfo info, SysDept dept,String roleName,String roleId) {
        //联系人作为机构管理员增加都用户表
        SysUser user = new SysUser();
        user.setDeptId(dept.getDeptId());
        user.setUserName(info.getContactPhone());
        user.setNickName(info.getContactName());
        user.setPhonenumber(info.getContactPhone());
        String initPassword = sysConfigMapper.selectInitPassword();
        user.setPassword(SecurityUtils.encryptPassword(initPassword));
        user.setCreateBy(dept.getCreateBy());
        user.setRemark(info.getRemark());
        sysUserMapper.insertUser(user);
        //分配角色
        if(roleId == null) {
            roleId = sysRoleMapper.getRoleIdByRoleKey(roleName)+"";
        }
        addRoles(user.getUserId(),roleId);
        return user;
    }


    /**
     * 添加角色
     * @param userId
     * @param roleId
     */
    @Override
    public void addRoles(Long userId,String roleId){
        List<SysUserRole> userRoleList = new ArrayList<>();
        String[] roleIds = roleId.split(",");
        for (String id : roleIds) {
            SysUserRole userRole = new SysUserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(Long.parseLong(id));
            userRoleList.add(userRole);
        }
        sysUserRoleMapper.batchUserRole(userRoleList);
    }

    /**
     * 环保局修改运维机构信息
     *
     * @param info
     * @param type 1环保局修改，2运维机构自己修改
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateOrganization(OpsOrganizationInfo info,int type) throws Exception {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        if(StringUtils.isEmpty(info.getCounty())){ //最起码到区县一级
            throw new Exception("请选择地址");
        }
        SysDept dept = null;
        if (type==1) {
            dept = sysDeptMapper.selectDeptById(info.getOpsId());
            //判断部门表是否存在同名
            if (dept != null && dept.getDeptId().intValue() != info.getOpsId().intValue()) {
                throw new Exception("修改失败，已存在相同名称企业，请核实");
            }
            //更新企业信息
            SysDept sysDept = new SysDept();
            sysDept.setDeptId(info.getOpsId());
            sysDept.setDeptName(info.getOpsName());
            sysDept.setStatus(info.getStatus());
            sysDept.setUpdateBy(sysUser.getNickName());
            sysDeptMapper.updateDept(sysDept);
            type = 1;
        }else{
            //运维机构只能修改自己的
            info.setOpsId(sysUser.getDeptId());
            dept = sysDeptMapper.selectDeptById(sysUser.getDeptId());
        }

        //判断用户表是否存在同手机号
        SysUser user = sysUserMapper.selectUserByUserName(info.getContactPhone());
        if (user != null) {
            if (user.getDeptId().intValue() != info.getOpsId().intValue()) {
                throw new Exception("修改失败，其他企业中已存在相同手机号账户，请核实");
            }
            //更换联系人
            info.setContactUserId(user.getUserId());
            //查看该用户是不是管理员，如果不是则添加管理员角色
            Set<String> role = user.getRoles().stream().map(SysRole::getRoleKey).collect(Collectors.toSet());
            if (!role.contains("opsAdmin")) {
                String roleId = sysRoleMapper.getRoleIdByRoleKey(OPS_ADMIN_ROLE_KEY) + "";
                addRoles(user.getUserId(), roleId);
            }
        }else{
            //账户不存在，新增
            SysUser newAdmin = addSysUser(info, dept,OPS_ADMIN_ROLE_KEY,null);
            info.setContactUserId(newAdmin.getUserId());
        }
        //更新运维机构其他基本信息
        opsOrganizationMapper.updateOpsOrganization(info,type);

    }

    /**
     * 查询运维机构列表
     *
     * @return
     */
    @Override
    public List<OpsOrganizationInfo> getOrganizationList(OpsOrganizationInfo info) {
        List<OpsOrganizationInfo> list = opsOrganizationMapper.getOrganizationList(info);
        //查询省市四级文字
        list.stream().forEach(item -> {
            StringBuilder addressCode = new StringBuilder();
            addressCode.append(item.getProvince()).append(",")
                    .append(item.getCity()).append(",")
                    .append(item.getCounty()).append(",")
                    .append(item.getTownship());
            String addressText = areaMapper.selectAddressByCode(addressCode.toString());
            item.setAddressText(addressText);
        });
        for (int i = 0; i < list.size(); i++) {
            OpsOrganizationInfo organizationInfo = list.get(i);
            getFileInfo(organizationInfo);
        }
        return list;
    }

    /**
     * 查询运维机构信息
     *
     * @param opsId 运维机构id
     * @return
     */
    @Override
    public OpsOrganizationInfo getInfoById(String opsId) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        if(sysUser.getDept().getType().intValue()==3){
            //运维机构只能查看自己公司信息
            opsId = Long.toString(sysUser.getDeptId());
        }
        OpsOrganizationInfo info = opsOrganizationMapper.getOrganizationById(Long.parseLong(opsId));
        //查询附件信息
        getFileInfo(info);
        //省市县区四级
        if(StringUtils.isNotEmpty(info.getTownship())) {
            StringBuilder addressCode = new StringBuilder();
            addressCode.append(info.getProvince()).append(",")
                    .append(info.getCity()).append(",")
                    .append(info.getCounty()).append(",")
                    .append(info.getTownship());
            String addressText = areaMapper.selectAddressByCode(addressCode.toString());
            info.setAddressText(addressText);
            info.setAddressText(addressText.substring(0,addressText.length()-1));
        }
        return info;
    }


    /**
     * 查询附件信息
     * @param info
     */
    private void getFileInfo(OpsOrganizationInfo info) {
        String fileIds = "";
        if(StringUtils.isNotEmpty(info.getCommitmentFileId())){
            fileIds += info.getCommitmentFileId()+",";
        }
        if(StringUtils.isNotEmpty(info.getQualificationFileId())){
            fileIds += info.getQualificationFileId()+",";
        }
        if(StringUtils.isNotEmpty(info.getOpsImageFileId())){
            fileIds += info.getOpsImageFileId()+",";
        }
        if(StringUtils.isNotEmpty(info.getIsoFileId())){
            fileIds += info.getIsoFileId()+",";
        }
        if(StringUtils.isNotEmpty(fileIds)){
            fileIds = fileIds.substring(0,fileIds.length()-1);
            List<FileUpload> fileUploads = fileUploadMapper.selectFileUploadListByIds(fileIds.split(","));
            List<Map> qualificationFileList = new ArrayList<>();
            List<Map> isoFileList = new ArrayList<>();
            for (int i = 0; i < fileUploads.size(); i++) {
                FileUpload fileUpload = fileUploads.get(i);
                if(fileUpload.getAttachmentId().equals(info.getCommitmentFileId())){
                    info.setCommitmentFile(fileUpload.getFileName());
                    info.setCommitmentFileUrl(fileUpload.getUrl());
                }else if(info.getQualificationFileId()!=null &&
                        info.getQualificationFileId().contains(fileUpload.getAttachmentId())){
                    qualificationFileList.add(FileUtil.structureFile(fileUpload));
                }else if(fileUpload.getAttachmentId().equals(info.getOpsImageFileId())){
                    info.setOpsImageFilePath(fileUpload.getUrl());
                    info.setOpsImageFile(fileUpload.getFileName());
                }else if(info.getIsoFileId()!=null &&
                        info.getIsoFileId().contains(fileUpload.getAttachmentId())){
                    isoFileList.add(FileUtil.structureFile(fileUpload));
                }
            }
            info.setQualificationFile(qualificationFileList);
            info.setIsoFile(isoFileList);
        }

    }

    /**
     * 运维机构新增用户
     *
     * @param map - userName 用户名
     *            - phone 手机号
     *            - roleId 角色id
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addUser(Map<String,String> map) throws Exception {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        String userName = map.get("userName");
        String phone = map.get("phone");
        String roleId = map.get("roleId");
        String remark = map.get("remark");
        if(StringUtils.isEmpty(userName)) {
            throw new Exception("姓名不能为空");
        }
        if(StringUtils.isEmpty(phone)) {
            throw new Exception("手机号不能为空");
        }
        //判断用户表是否存在同手机号
        SysUser user = sysUserMapper.selectUserByUserName(phone);
        if (user != null) {
            throw new Exception("修改失败，已存在相同手机号账户，请核实");
        }

        OpsOrganizationInfo info = new OpsOrganizationInfo();
        info.setContactName(userName);
        info.setContactPhone(phone);
        info.setRemark(remark);
        SysDept dept = sysUser.getDept();
        dept.setCreateBy(sysUser.getNickName());
        addSysUser(info, dept,OPS_USER_ROLE_KEY,roleId);
    }



    /**
     * 修改用户
     *
     * @param map
     */
    @Override
    public void updateUser(Map map) throws Exception {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        String roleId = String.valueOf(map.get("roleId"));
        String userId = String.valueOf(map.get("userId"));
        String phone = String.valueOf(map.get("phone"));
        String status = String.valueOf(map.get("status"));
        if(StringUtils.isEmpty(roleId)) {
            throw new Exception("至少需要有一个岗位");
        }

        //判断用户表是否存在同手机号
        SysUser existUser = sysUserMapper.selectUserByUserName(phone);
        if (existUser != null && !userId.equals(existUser.getUserId().toString())) {
            throw new Exception("修改失败，已存在相同手机号账户，请核实");
        }

        //判断本次修改是不是去掉了管理员权限，至于要有一个管理员账号
        List<Map> roles = sysRoleMapper.getAdminRole(sysUser.getDeptId(),OPS_ADMIN_ROLE_KEY);
        if(roles.size() == 1){
            Map role = roles.get(0);
            //查看是否是当前修改的
            if(userId.equals(role.get("userId").toString())){
                if(!roleId.contains(role.get("roleId").toString())){
                    throw new Exception("至少需要有一个管理员");
                }
                if(StringUtils.isNotEmpty(status) && !"0".equals(status)){
                    throw new Exception("至少需要有一个管理员");
                }
            }
        }
        SysUser user = new SysUser();
        user.setUserId(Long.parseLong(userId));
        user.setNickName(String.valueOf(map.get("userName")));
        user.setUserName(String.valueOf(map.get("phone")));
        user.setPhonenumber(phone);
        user.setRemark(String.valueOf(map.get("remark")));
        user.setUpdateBy(sysUser.getNickName());
        user.setStatus(status);
        sysUserMapper.updateUser(user);
        //删除角色，重新保存
        userRoleMapper.deleteUserRoleByUserId(Long.parseLong(userId));
        // 新增用户与角色管理
        addRoles(Long.parseLong(userId),roleId);
    }

    /**
     * 批量导入人员
     *
     * @param list
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer addUserBatch(List<CompanyContactExcel> list) throws Exception {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        SysDept dept = sysUser.getDept();
        dept.setCreateBy(sysUser.getNickName());
        for (int i = 0; i < list.size(); i++) {
            CompanyContactExcel data = list.get(i);
            SysUser user = sysUserMapper.selectUserByUserName(data.getPhone());
            if (user != null && "0".equals(user.getDelFlag()))  {
                throw new Exception("导入失败，"+data.getPhone()+"已存在相同手机号账户，请核实");
            }
            OpsOrganizationInfo info = new OpsOrganizationInfo();
            info.setContactName(data.getName());
            info.setContactPhone(data.getPhone());
            info.setRemark(data.getRemark());
            addSysUser(info, dept,OPS_USER_ROLE_KEY,null);
        }
        return list.size();
    }

    /**
     * 修改运维机构状态：
     *
     * @param id
     * @param status 0正常、1禁用、2删除
     */
    @Override
    public void updateStatus(Long id, String status) throws Exception {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        SysDept dept = new SysDept();
        dept.setDeptId(id);
        if(!"0,1,2".contains(status)){
            throw new Exception("参数错误");
        }
        if("2".equals(status)){
            dept.setDelFlag("2");//删除
            dept.setStatus("1");//状态停用
        }else {
            dept.setStatus(status);
        }
        dept.setUpdateBy(user.getNickName());
        sysDeptMapper.updateDept(dept);
    }

    /**
     * 批量导入运维机构
     *
     * @param list
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void batchInsert(List<OpsOrganizationInfo> list) throws Exception {
        int row = 1;
        for (OpsOrganizationInfo info : list) {
            try {
                //省市县转换为code
                Area province = areaMapper.selectAddressByName(info.getProvince(),null);
                if(province==null){
                    throw new Exception("第"+row+"行错误：省选择错误");
                }
                Area city = areaMapper.selectAddressByName(info.getCity(),province.getCode());
                if(city == null){
                    throw new Exception("第"+row+"行错误：市选择错误");
                }
                Area county = areaMapper.selectAddressByName(info.getCounty(),city.getCode());
                if(county==null){
                    throw new Exception("第"+row+"行错误：县区选择错误");
                }
                Area township = areaMapper.selectAddressByName(info.getTownship(),county.getCode());
                if(township==null) {
                    throw new Exception("第"+row+"行错误：乡镇/街道选择错误");
                }
                info.setProvince(province.getCode());
                info.setCity(city.getCode());
                info.setCounty(county.getCode());
                info.setTownship(township.getCode());
                addOrganization(info);
            } catch (Exception e) {
                throw new Exception("第"+row+"行错误："+e.getMessage());
            }
            row++;
        }
    }
}
